﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Revit;
using YJKTextDimension.Utility;

namespace YJKTextDimension.DimCreator
{
	internal class DimensionHide
	{
		public DimensionHide(UIApplication m_uiApp)
		{
			UIDocument activeUIDocument = m_uiApp.ActiveUIDocument;
			this.doc = activeUIDocument.Document;
			this.sel = activeUIDocument.Selection;
		}

		public void Excute(RequestId id, bool state)
		{
			switch (id)
			{
			case RequestId.None:
				break;
			case RequestId.ViewTwoPoint:
			{
				string typeName = "TwoPointDim";
				this.ViewHide(typeName, state);
				return;
			}
			case RequestId.SelectTwoPoint:
			{
				string typeName = "TwoPointDim";
				this.SelectHide(typeName, state);
				return;
			}
			case RequestId.ViewDoorWin:
			{
				string typeName = "DoorWindowDim";
				this.ViewHide(typeName, state);
				return;
			}
			case RequestId.SelectDoorWin:
			{
				string typeName = "DoorWindowDim";
				this.SelectHide(typeName, state);
				return;
			}
			case RequestId.ViewWallThick:
			{
				string typeName = "WallThickDim";
				this.ViewHide(typeName, state);
				return;
			}
			case RequestId.SelectWallThick:
			{
				string typeName = "WallThickDim";
				this.SelectHide(typeName, state);
				return;
			}
			case RequestId.ViewAxis:
			{
				string typeName = "AxisDim";
				this.ViewHide(typeName, state);
				return;
			}
			case RequestId.SelectAxis:
			{
				string typeName = "AxisDim";
				this.SelectHide(typeName, state);
				break;
			}
			default:
				return;
			}
		}

		private void SelectHide(string typeName, bool isHide)
		{
			HideDimensionFilter hideDimensionFilter = new HideDimensionFilter(typeName);
			Transaction transaction = null;
			try
			{
				transaction = new Transaction(this.doc, "HideDim");
				for (;;)
				{
					transaction.Start();
					List<Dimension> hideDimensions = (from d in this.sel.PickElementsByRectangle(hideDimensionFilter, "框选要归属于选定类别的标注")
					select d as Dimension).ToList<Dimension>();
					if (isHide)
					{
						this.SelHiddenDimension(typeName, hideDimensions);
					}
					else
					{
						this.SelDisplayDimension(typeName, hideDimensions);
					}
					transaction.Commit();
				}
			}
			catch (Autodesk.Revit.Exceptions.OperationCanceledException)
			{
			}
			finally
			{
				if (transaction != null)
				{
					TransactionStatus status = transaction.GetStatus();
					if (status != (TransactionStatus)3)
					{
						transaction.RollBack();
					}
				}
			}
		}

		private void ViewHide(string typeName, bool isHide)
		{
			Transaction transaction = null;
			try
			{
				transaction = new Transaction(this.doc, "HideDim");
				transaction.Start();
				if (isHide)
				{
					this.HiddenDimension(typeName);
				}
				else
				{
					this.DisplayDimension(typeName);
				}
				transaction.Commit();
			}
			catch (Autodesk.Revit.Exceptions.OperationCanceledException)
			{
			}
			finally
			{
				if (transaction != null)
				{
					TransactionStatus status = transaction.GetStatus();
					if (status != (TransactionStatus)3)
					{
						transaction.RollBack();
					}
				}
			}
		}

		private void HiddenDimension(string typeName)
		{
			List<Dimension> hideDimensions = this.GetHideDimensions(typeName);
			if (hideDimensions.Count > 0)
			{
				this.Hide(hideDimensions);
			}
		}

		private void DisplayDimension(string typeName)
		{
			ElementSet elementSet = new ElementSet();
			List<Dimension> showDimensions = this.GetShowDimensions(typeName);
			foreach (Dimension dimension in showDimensions)
			{
				elementSet.Insert(dimension);
			}
			if (elementSet.Size > 0)
			{
				this.doc.ActiveView.UnHideYJKElements(elementSet);
			}
		}

		private void SelHiddenDimension(string typeName, List<Dimension> hideDimensions)
		{
			foreach (Dimension dim in hideDimensions)
			{
				DimPublicFunc.SetDimFlag(dim, typeName);
			}
			this.Hide(hideDimensions);
		}

		private void SelDisplayDimension(string typeName, List<Dimension> hideDimensions)
		{
			foreach (Dimension dim in hideDimensions)
			{
				DimPublicFunc.SetDimFlag(dim, typeName);
			}
		}

		private void Hide(List<Dimension> hideDimensions)
		{
			ElementSet elementSet = new ElementSet();
			foreach (Element element in hideDimensions)
			{
				elementSet.Insert(element);
			}
			if (elementSet.Size > 0)
			{
				this.doc.ActiveView.HideYJKElements(elementSet);
			}
		}

		private List<Dimension> GetHideDimensions(string typeName)
		{
			List<Dimension> list = new List<Dimension>();
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.doc, this.doc.ActiveView.Id);
			List<Dimension> list2 = (from d in filteredElementCollector.OfClass(typeof(Dimension)).OfCategory(BuiltInCategory.OST_Dimensions)
			select d as Dimension).ToList<Dimension>();
			foreach (Dimension dimension in list2)
			{
				string dimFlag = DimPublicFunc.GetDimFlag(dimension);
				if (!string.IsNullOrEmpty(dimFlag) && dimFlag == typeName)
				{
					list.Add(dimension);
				}
			}
			return list;
		}

		private List<Dimension> GetShowDimensions(string typeName)
		{
			List<Dimension> list = new List<Dimension>();
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.doc);
			List<Dimension> list2 = (from d in filteredElementCollector.OfClass(typeof(Dimension)).OfCategory(BuiltInCategory.OST_Dimensions)
			select d as Dimension).ToList<Dimension>();
			foreach (Dimension dimension in list2)
			{
				if (dimension.View != null && dimension.View.Id.IntegerValue == this.doc.ActiveView.Id.IntegerValue)
				{
					string dimFlag = DimPublicFunc.GetDimFlag(dimension);
					if (!string.IsNullOrEmpty(dimFlag) && dimFlag == typeName)
					{
						list.Add(dimension);
					}
				}
			}
			return list;
		}

		private Document doc;

		private Selection sel;
	}
}
